AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )

include('shared.lua')

ENT.WireDebugName = "Radial Radio Transmitter"

local MODEL = Model("models/radio/ra_cell_tower1.mdl")

function ENT:Initialize()
	self.Entity:SetModel( MODEL )
	self.Entity:PhysicsInit( SOLID_VPHYSICS )
	self.Entity:SetMoveType( MOVETYPE_VPHYSICS )
	self.Entity:SetSolid( SOLID_VPHYSICS )
	self.Entity:StartMotionController()

	self.Inputs = Wire_CreateInputs(self.Entity, { "Active", "Frequency", "Secure Code [STRING]", "Data [ARRAY]" })
	self.Outputs = Wire_CreateOutputs(self.Entity, { "Active", "Frequency", "Secure" })
	
	self.On = false
	self.Secure = ""
	self.Freq = 720
	self.Data = {}
	self.MaxDiff = 3.17 --Maximum frequency difference
	self.Range = 34000
	self.RangeP = 30600
	self.RangeP2 = 25900
	self.RangeW = 8700
	self.Antennas = { ["models/radio/ra_cell_tower1.mdl"] = Vector(0,0,142) }
end

function ENT:Setup(m)
	MODEL = Model(m)
end

function ENT:Output()
	
end

function ENT:TriggerInput(name, val)
	if name == "Active" then
		self.On = (val > 0)
	elseif name == "Frequency" then
		self.Freq = math.Clamp(val,720,1600)
	elseif name == "Secure Code" then
		self.Secure = val
	elseif name == "Data" then
		self.Data = val
	end
end

local function Freq(self,d)
	local d2 = self.Freq
	local r1 = false
	local dif = math.abs(d2-d)
	if dif <= self.MaxDiff then
		r1 = true
	end
	return r1
end

local function Range(self,d)
	local d1 = self.Entity:LocalToWorld(self.Antennas[d:GetModel()] or Vector(0,0,0))
	local p = d:LocalToWorld(self.Antennas[d:GetModel()] or Vector(0,0,0))
	local dist = (d1-p):LengthSqr()
	local trd, trd2 = {}, {}
	trd.start, trd.endpos, trd.filter = d1, p, self.Entity
	trd2.start, trd2.endpos, trd2.filter = p, d1, d
	local tr = util.TraceLine(trd)
	local tr2 = util.TraceLine(trd2)
	local vis = (tr.Entity == d)
	if vis then
		--print("Visible")
		return math.pow(self.Range,2) >= dist
	elseif not vis and tr2.Entity == tr.Entity and not tr.HitWorld then
		--print("Hit prop!")
		return math.pow(self.RangeP,2) >= dist
	elseif not vis and tr2.Entity != tr.Entity and not tr.HitWorld then
		--print("Hit 2 props!")
		return math.pow(self.RangeP2,2) >= dist
	else
		--print("Not visible")
		return math.pow(self.RangeW,2) >= dist
	end
end

function ENT:Think()
	if self.On then
		for k,v in pairs(ents.FindByClass("gmod_wire_radio_receiver")) do
			local f1 = Freq(self,v.Freq)
			local r1 = Range(self,v,f2)
			local function own(a,b)
				local s1, s2 = a.Secure, b.Secure
				if s1 == "" and s2 == "" then return true end
				if s1 != "" and s1 == s2 then return true end
				return false
			end
			if f1 and r1 and own(self,v) then
				v.Data[self.Entity] = self.Data
			else
				v.Data[self.Entity] = nil	
			end
		end
	else
		for k,v in pairs(ents.FindByClass("gmod_wire_radio_receiver")) do
			v.Data[self.Entity] = nil
		end
	end
	Wire_TriggerOutput(self.Entity, "Active", self.On and 1 or 0)
	Wire_TriggerOutput(self.Entity, "Frequency", self.Freq)
	Wire_TriggerOutput(self.Entity, "Secure", self.Secure != "" and 1 or 0)
	self:NextThink(CurTime()+0.1)
end

function ENT:ShowOutput()
	
end

function ENT:TriggerOutput(out)
    
end
